home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util3 / floppy.lha / floppy / installgen.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  8KB  |  242 lines

  1. /***************************************************************************/
  2. /*           INSTALL A CUSTOM BOOTBLOCK TO ANY DISK                        */
  3. /* Compiler: SAS/C  V6.51                                           ORHAN  */
  4. /***************************************************************************/
  5. #define __USE_SYSBASE
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9. #include <exec/io.h>
  10. #include <exec/ports.h>
  11. #include <dos/dos.h>
  12. #include <dos/filehandler.h>
  13. #include <dos/dosextens.h>
  14. #include <dos/rdargs.h>
  15. #include <devices/trackdisk.h>
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18. #include <proto/utility.h>
  19.  
  20. long   SetBoot(UBYTE *bootblock, ULONG length, LONG key);
  21. void   ClrBoot(UBYTE *bootblock, ULONG length);
  22. long   BootChkSum(UBYTE *bootblock, ULONG length);
  23. void   PutDosType(ULONG *bootblock);
  24. void   GetLenBoot(void);
  25. struct DeviceNode *findentry(struct DeviceNode *dn, UBYTE *name, LONG type);
  26. long   readsector(UBYTE *buf, ULONG offset, ULONG length);
  27. long   writesector(UBYTE *buf, ULONG offset, ULONG length);
  28. long   update(void),motoron(void),motoroff(void);
  29.  
  30. struct DosInfo     *di;
  31. struct DeviceNode  *dn;
  32. struct DosEnvec    *de;
  33. struct FileSysStartupMsg *fssm;
  34. struct IOStdReq    *devreq=NULL;
  35. struct MsgPort     *devport=NULL;
  36. struct RDArgs      *rdargs=NULL;
  37. struct InfoData    *infodata=NULL;
  38. struct FileLock    *flock;
  39. UBYTE  version[]   ="$VER: InstallGen 1.0 (12.01.95) © by OR\r\n";
  40. enum   {ARG_DRIVE,ARG_NOBOOT,ARG_CHECK,ARGCOUNT};
  41. LONG   myarray[ARGCOUNT];
  42. UBYTE  *devname;
  43. UWORD  openstatus=NULL;
  44. UBYTE  *buffer=NULL;
  45. ULONG  lenbuf,offset;
  46. ULONG  lenboot=NULL;
  47. BPTR   lock=NULL;
  48. LONG   rc=NULL,rcio=NULL;
  49. UBYTE  *str0 = "there is no bootblock\n";
  50. UBYTE  *str1 = "not bootable";
  51. UBYTE  *str2 = "bootblock ok";
  52. UBYTE  *str3 = "bootblock size invalid\n";
  53.  
  54.  
  55. long installgen(void)
  56. {
  57.        SysBase = (*((struct ExecBase **)0x4));
  58.        DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36);
  59.        if (DOSBase==NULL) goto cleanexit;
  60.        UtilityBase = OpenLibrary("utility.library",NULL);
  61.        if (UtilityBase==NULL) goto cleanexit;
  62.       
  63.        rdargs = ReadArgs("DRIVE/A,"
  64.                          "NOBOOT/S,"
  65.                          "CHECK/S",&myarray[0],NULL);
  66.  
  67.        if (!rdargs) {rc=IoErr(); goto cleanexit;}
  68.  
  69.        Forbid();
  70.        di=(struct DosInfo *)BADDR(DOSBase->dl_Root->rn_Info);
  71.        dn = findentry((struct DeviceNode *)&di->di_DevInfo,(UBYTE *)myarray[ARG_DRIVE],DLT_DEVICE);
  72.        Permit();
  73.  
  74.        if (dn==DOSFALSE) {rc=ERROR_OBJECT_NOT_FOUND; goto cleanexit;}
  75.  
  76.        fssm=(struct FileSysStartupMsg *)BADDR(dn->dn_Startup);
  77.        if ((ULONG)fssm<0x400 || dn->dn_Task==NULL)
  78.                {rc=ERROR_OBJECT_WRONG_TYPE; goto cleanexit;}
  79.  
  80.        de = (struct DosEnvec *)BADDR(fssm->fssm_Environ); 
  81.        if (de->de_TableSize<9) {rc=ERROR_OBJECT_WRONG_TYPE; goto cleanexit;}
  82.  
  83.        offset = de->de_SizeBlock*4 *
  84.                 de->de_BlocksPerTrack * 
  85.                 de->de_Surfaces *
  86.                 de->de_LowCyl;
  87.  
  88.        lenbuf = de->de_SizeBlock*4*de->de_Reserved;
  89.        if (lenbuf==0) {rc=ERROR_OBJECT_WRONG_TYPE; goto cleanexit;}
  90.  
  91.        buffer=AllocVec(lenbuf,de->de_BufMemType);
  92.        infodata=AllocVec(sizeof(struct InfoData),MEMF_PUBLIC);
  93.        devport = CreateMsgPort();
  94.        devreq = CreateIORequest(devport,sizeof(struct IOStdReq));
  95.        if (buffer==NULL || devport==NULL || devreq==NULL || infodata==NULL)
  96.                             {rc=ERROR_NO_FREE_STORE; goto cleanexit;}
  97.  
  98.        devname=(UBYTE *)BADDR(fssm->fssm_Device); devname++;
  99.        rcio = OpenDevice(devname,fssm->fssm_Unit,(struct IORequest *)devreq,fssm->fssm_Flags);
  100.        if (rcio) goto cleanexit; openstatus=1;
  101.  
  102.        if (myarray[ARG_CHECK]==NULL) {
  103.        lock=Lock((UBYTE *)myarray[ARG_DRIVE],ACCESS_READ);
  104.        if (lock==NULL) {rc=IoErr(); goto cleanexit;}
  105.        if (Info(lock,infodata)==DOSFALSE) {rc=IoErr(); goto cleanexit;}
  106.        flock=BADDR(lock);
  107.        GetLenBoot(); if (lenboot==0) goto cleanexit;
  108.        if (infodata->id_DiskState==ID_WRITE_PROTECTED)
  109.                            {rc=ERROR_DISK_WRITE_PROTECTED; goto cleanexit;}
  110.        rcio = motoron(); if (rcio) goto cleanexit;
  111.                                      }
  112.  
  113.        rcio = readsector(buffer,offset,lenbuf); if (rcio) goto cleanexit;
  114.  
  115.  
  116.        if (myarray[ARG_CHECK]) {
  117.        PutStr("Appears to be "); PutDosType((ULONG *)buffer); PutStr(" disk, ");
  118.        GetLenBoot(); if (lenboot==0) goto cleanexit;
  119.        if (BootChkSum(buffer,lenboot)) PutStr(str1); else PutStr(str2);
  120.        VPrintf(", its size %ld bytes\n",&lenboot);
  121.                                }
  122.  
  123.        else if (myarray[ARG_NOBOOT]) {
  124.        ClrBoot(buffer,lenboot);
  125.        rcio = writesector(buffer,offset,lenboot); if (rcio) goto cleanexit;
  126.        rcio = update();                           if (rcio) goto cleanexit;
  127.        PutStr("Bootblock cleared\n");
  128.                                      }
  129.  
  130.        else if (myarray[ARG_DRIVE]) {
  131.        rcio = SetBoot(buffer,lenboot,flock->fl_Key); if (rcio) goto cleanexit;
  132.        rcio = writesector(buffer,offset,lenboot);    if (rcio) goto cleanexit;
  133.        rcio = update();                              if (rcio) goto cleanexit;
  134.        PutStr("Bootblock installed\n");
  135.                                     }
  136.  
  137.  
  138. cleanexit:
  139.         if (openstatus) {motoroff(); CloseDevice((struct IORequest *)devreq);}
  140.         if (devreq) DeleteIORequest(devreq);
  141.         if (devport) DeleteMsgPort(devport);
  142.         if (lock) UnLock(lock);
  143.         if (rdargs) FreeArgs(rdargs);
  144.  
  145.         if (rc==0 && rcio==TDERR_DiskChanged) {rc=ERROR_NO_DISK; rcio=0;}
  146.         if (rc) PrintFault(rc,NULL); else if (rcio>0) rc=rcio;
  147.         if (rcio<0) PutStr("Bootblock is very small\n");
  148.         if (rcio>0) PutStr("Unable to read from or write to volume\n");
  149.  
  150.         if (UtilityBase) CloseLibrary(UtilityBase);
  151.         if (DOSBase) CloseLibrary((struct Library *)DOSBase);
  152.         if (buffer) FreeVec(buffer);
  153.         if (infodata) FreeVec(infodata);
  154.         return(rc);
  155. }
  156.  
  157.  
  158. void GetLenBoot(void)
  159. {
  160.        if (de->de_TableSize<19) PutStr(str0);
  161.        else {lenboot = de->de_SizeBlock*4*de->de_BootBlocks;
  162.              if (lenboot==0 || de->de_BootBlocks > de->de_Reserved)
  163.                                                  PutStr(str3);
  164.             }
  165. }
  166.  
  167.  
  168. struct DeviceNode *findentry(struct DeviceNode *dn, UBYTE *name, LONG type)
  169. {
  170. UBYTE *name2;
  171. ULONG len;
  172.          /* first node is initial ptr to DosList !*/
  173.  
  174.        while(dn=(struct DeviceNode *)BADDR(dn->dn_Next)) { 
  175.            name2 = BADDR(dn->dn_Name); len=*name2++;
  176.            if (dn->dn_Type == type && 
  177.                Strnicmp(name,name2,len)==0 &&
  178.                *(name+len)==':') break;
  179.                                                          }
  180.  
  181.       return(dn);
  182. }
  183.  
  184.  
  185. void PutDosType(ULONG *buf)
  186. {
  187.           switch(*buf) {
  188.       case ID_DOS_DISK:         PutStr("OFS"); break;        
  189.       case ID_FFS_DISK:         PutStr("FFS"); break;        
  190.       case ID_INTER_DOS_DISK:   PutStr("OFS-INT"); break;    
  191.       case ID_INTER_FFS_DISK:   PutStr("FFS-INT"); break;    
  192.       case ID_FASTDIR_DOS_DISK: PutStr("OFS-DC"); break;    
  193.       case ID_FASTDIR_FFS_DISK: PutStr("FFS-DC"); break;    
  194.               default:          PutStr("unknown"); break;    
  195.                        }
  196. }
  197.  
  198.  
  199. long motoron(void)
  200. {
  201.      devreq->io_Command = TD_MOTOR;
  202.      devreq->io_Length = 1;
  203.      return(DoIO((struct IORequest *)devreq));
  204. }
  205.  
  206.  
  207. long motoroff(void)
  208. {
  209.      devreq->io_Command = TD_MOTOR;
  210.      devreq->io_Length = 0;
  211.      return(DoIO((struct IORequest *)devreq));
  212. }
  213.  
  214.  
  215. long update(void)
  216. {
  217.      devreq->io_Command = CMD_UPDATE;
  218.      return(DoIO((struct IORequest *)devreq));
  219. }
  220.  
  221.  
  222. long readsector(UBYTE *buf, ULONG offset, ULONG length)
  223. {
  224.      devreq->io_Length = length;
  225.      devreq->io_Data = (APTR)buf;
  226.      devreq->io_Command = CMD_READ;
  227.      devreq->io_Offset = offset;
  228.      return(DoIO((struct IORequest *)devreq));
  229. }
  230.  
  231.  
  232. long writesector(UBYTE *buf, ULONG offset, ULONG length)
  233. {
  234.      devreq->io_Length = length;
  235.      devreq->io_Data = (APTR)buf;
  236.      devreq->io_Command = CMD_WRITE;
  237.      devreq->io_Offset = offset;
  238.      return(DoIO((struct IORequest *)devreq));
  239. }
  240. /*
  241. */
  242.